package com.eastcom.collection.process

import com.eastcom.collection.tools.db.DerByUtil;
import com.eastcom.collection.distributor.*

import java.sql.*
import java.text.SimpleDateFormat
import java.util.List;
import java.util.Map;

import com.eastcom.collection.tools.db.*
import com.eastcom.collection.provider.*

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
import org.springframework.stereotype.Component
import org.apache.log4j.Logger;
@Component("dataCacheProcess")
class DataCacheProcess extends Thread{
	private static Logger logger = Logger.getLogger(DataCacheProcess.class);
	final static List<String> cacheRead = new ArrayList<String>()
	final static List<String> cacheWrite = new ArrayList<String>()
	final String selectSql = "select DATA from DATACACHE where {fn TIMESTAMPDIFF(SQL_TSI_SECOND,CREATETIME,CURRENT_TIMESTAMP)}<36000"
	final String deleteSql = "delete from DATACACHE where {fn TIMESTAMPDIFF(SQL_TSI_SECOND,CREATETIME,CURRENT_TIMESTAMP)}<36000"
	final String insertSql = "insert into DATACACHE(CREATETIME,DATA) values(CURRENT_TIMESTAMP,?)"
	final String createSql = "create table DATACACHE(ID INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1) primary key,CREATETIME TIMESTAMP, DATA VARCHAR(1024) NOT NULL)"
	Map<String, Boolean> dataBaseStatus = new HashMap<String, Boolean>()
	private static Map<String, Integer[]> sqlTypeList = new HashMap<String, Integer[]>()
	private static List<String> timeFormatList = new ArrayList<String>()
	private boolean on = true

	@Override
	public void run() {
		// TODO 自动生成的方法存根
		println "fffffffffffffddfff"
		initJob()
		while(on){
			println "ffffffffffffffff"
			doJob()
			Thread.sleep(5000)
		}
	}

	public boolean initJob(){
		String timeFmt = PropertyPlaceholderConfigurerProvider.getContextProperty("TimeFormate")
		if(timeFmt == null){
			timeFmt = "yyyy-MM-dd HH:mm:ss,yyyy/MM/dd HH:mm:ss,yyyy-MM-dd,yyyy/MM/dd"
		}
		String[] timeFormate = timeFmt.split("\\s*,\\s*")
		timeFormate.each {
			timeFormatList.add(it)
		}
	}

	public boolean doJob(){
		Connection conn = null
		try {
			conn = DerByUtil.getNetwrokConnect("//localhost:1527/DATACACHE")
		} catch (Exception e) {
			e.printStackTrace()
			logger.error(this, e)
			return false
		}
		Statement stmt = null;
		ResultSet rs = null;
		insertCache()
		try {
			println "dddddddddd"
			PreparedStatement pst = conn.prepareStatement(selectSql)
			logger.debug("开始查询缓存。。。")
			ResultSet res = pst.executeQuery()
			println res
			while (res != null && res.next()) {
				println res.getString(1)
				cacheRead.add(res.getString(1))
				logger.debug("读到了缓存："+res.getString(1))
			}

			for(String line: cacheRead){
				if(!parseLine(line)){
					println "解析失败！"
					cacheWrite.add(line)
				}
			}
			cacheRead.clear()
			if(!cacheWrite.isEmpty()){
				DPService.cacheData.addAll(cacheWrite)
				cacheWrite.clear()
			}
			pst = conn.prepareStatement(deleteSql)
			pst.executeUpdate()
			insertCache()
		} catch (Exception ex) {
			logger.error(this, ex)
		} finally {
			try {
				rs.close();
			} catch (Exception e) {
			}
			rs = null;
			try {
				stmt.close();
			} catch (Exception e) {
			}
			stmt = null;
			try {
				conn.close();
			} catch (Exception e) {
			}
			conn = null;
		}

	}
	private boolean insertCache(){
		Connection conn = null
		try {
			conn = DerByUtil.getNetwrokConnect("//localhost:1527/DATACACHE")
		} catch (Exception e) {
			e.printStackTrace()
			logger.error(this, e)
			return false
		}
		while(!DPService.cacheData.isEmpty()){
			String line = DPService.cacheData.poll()
			try {
				if(conn == null){
					try {
						conn = DerByUtil.getNetwrokConnect("//localhost:1527/DATACACHE")
					} catch (Exception e) {
						e.printStackTrace()
						logger.error(this, e)
						return false
					}
				}
				PreparedStatement pst = conn.prepareStatement(insertSql)
				pst.setString(1, line)
				int cnt = pst.executeUpdate()
				if(cnt < 1){
					logger.error("插入缓存失败！")
				}
				println "写到了缓存："+line
			} catch (Exception ex) {
				ex.printStackTrace()
				logger.error(this, ex)
			}
		}
	}
	public static boolean parseLine(String line){
		try {
			List<String> valueList = new ArrayList<String>()
			String[] values = line.split("\\|\\|")
			if(values == null || values.length <= 3){
				return
			}
			for(int i = 3; i < values.length; i++){
				valueList.add(values[i])
			}
			StringBuffer sqlBf = new StringBuffer()
			sqlBf.append("insert into ")
			println values[1]+"----"+values[2]
			String table = DPService.table.get(values[1])

			Map<String,String> feildList = DPService.feild.get(values[1])
			println table
			if(table == null){
				return false
			}
			sqlBf.append(table+"(")
			for(int i = 0; i < values[2].trim().length(); i++){
				char c = values[2].charAt(i)
				String seq = c.toString()
				sqlBf.append(feildList.get(seq))
				if(i < values[2].trim().length()-1){
					sqlBf.append(",")
				}
			}
			sqlBf.append(") values(")
			for(int i = 0; i < values[2].trim().length(); i++){
				sqlBf.append("?")
				if(i < values[2].trim().length()-1){
					sqlBf.append(",")
				}
			}
			sqlBf.append(")")
			if(!doInsertResult(valueList,sqlBf.toString(),values[1])){
				println "add a new line into cache"
				return false
			}
		} catch (Exception e) {
			logger.error(this, e)
			return false
		}
		return true
	}

	public static boolean doInsertResult(List<String> raw, String sql, String tbId){
		DbEngine dbEngine = SpringContextProvider.getBean("dbEngine")
		List<String> dbList = DPService.actionRuleList.get(tbId)
		List<String> dstFieldList = new ArrayList()
		List<Integer> dstFieldTypeList = new ArrayList()
		try {
			dbList.each {
				dbEngine.getJdbcUtil().setDataSource(SpringContextProvider.getBean(it))
				int[] sqlTypes = sqlTypeList.get(tbId)
				if(sqlTypes == null || sqlTypes.length == 0){
					sql = DbEngine.doDbInit(it, dstFieldList, dstFieldTypeList, sql, false)
					sqlTypes = new int[dstFieldTypeList.size()]
					for(int i = 0; i < dstFieldTypeList.size(); i++){
						sqlTypes[i] = dstFieldTypeList.get(i)
					}
					sqlTypeList.put(tbId, sqlTypes)
				}
				Object[] param = new Object[raw.size()]
				for(int i = 0; i < raw.size(); i++){
					String value = raw.get(i)
					switch(sqlTypes[i]){
						case Types.INTEGER:
							param[i] = Integer.valueOf(value)
							break
						case Types.FLOAT:
						case Types.DOUBLE:
							param[i] = Double.valueOf(value)
							break
						case Types.DECIMAL:
						case Types.NUMERIC:
							param[i] = BigDecimal.valueOf(Double.valueOf(value))
							break
						case Types.TIMESTAMP:
							java.util.Date date = null;
							Timestamp time
							boolean isFd = false
							for(int j = 0; j < timeFormatList.size(); j++) {
								try {
									SimpleDateFormat simpleDateFormat = new SimpleDateFormat(timeFormatList.get(j));
									date = simpleDateFormat.parse(value)
									println(date)
									isFd = true
									break;
								} catch (Exception e) {
									// TODO: handle exception
									println("时间转换错误！时间："+value+"格式："+timeFormatList.get(j))
									continue
								}
							}
							logger.debug(date.toLocaleString());
							SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.sss");
							String string = simpleDateFormat2.format(date);
							logger.debug(string);
							Timestamp timestamp = Timestamp.valueOf(string);
							param[i] = timestamp
							break
						case Types.DATE:
							java.util.Date date = null;
							boolean isFd = false
							for(int j = 0; j < timeFormatList.size(); j++) {
								try {
									SimpleDateFormat simpleDateFormat = new SimpleDateFormat(timeFormatList.get(j));
									date = simpleDateFormat.parse(value)
									println(date)
									isFd = true
									break;
								} catch (Exception e) {
									// TODO: handle exception
									println("时间转换错误！时间："+value+"格式："+timeFormatList.get(j))
									continue
								}
							}
							logger.debug(date.toLocaleString());
							SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.sss");
							String string = simpleDateFormat2.format(date);
							logger.debug(string);
							param[i] = new java.sql.Date(date.getTime())
							break
						case Types.VARCHAR:
						case Types.NVARCHAR:
							param[i] = value
							break
						case Types.OTHER:
							param[i] = value
							break;
						default:
							param[i] = null
							logger.warn("入库数据库字段无法识别！使用Null插入！")
							break;
					}

				}
				dbEngine.getJdbcUtil().update(sql, param, sqlTypes)
			}
		} catch (Exception e) {
			logger.error(this, e)
			return false
		}

		return true
	}
}
